The invention relates to "software monitors" that enable a user to define break points in user software being debugged or analyzed in order to allow the user to step through or otherwise advance through the user program and determine the contents of the registers of a processor at selected software break points.
Programs called software monitors, or simply "monitors", commonly are used in computer systems to enable engineers to "debug" or analyze software. A monitor typically enables an engineer to input "monitor commands" to the monitor by means of a terminal. The monitor commands are a set of commands, each of which usually consists of one to three letters. Such monitor commands enable a user to inspect and modify certain microprocessor variables or memory locations in a memory used by the microprocessor.
For example, a typical command is "display data memory", which when entered with a numeric address value via a terminal, instructs the software monitor to display on the terminal screen the contents of a certain number of memory locations, starting from the specified numeric address. Another typical command is a "modify register" command whereby the contents of a specified register of the microprocessor may be examined and modified. The monitor command set also contains commands to allow a user to load a user program into memory, run the user program, and halt the user program at a certain stage of its execution to examine the effect of the user program on the microprocessor registers and any relevant locations in memory.
To halt the execution of a user program, a software break point is set at the particular location in memory where a halt is desired. The software break point causes the microprocessor to stop executing the user program, save all the current values of its registers in a certain area of memory reserved for exclusive use by the monitor, and then start executing the monitor program.
A typical sequence of events would be as follows. From "power up" of a system based on a microprocessor, the system would automatically start running a resident software monitor program. This would allow monitor commands to be entered by means of a terminal. Using the monitor commands, the user would enter a user program into the system memory, starting at a certain address. The user then would initialize all the relevant microprocessor registers to the values required at the start of execution of the user program. In particular, the user program counter (which contains the address of the memory location containing the next user instruction to be executed by the microprocessor if it were running a user program) is set to the address value of the beginning of the user program. The user then would set a software break point in the user program using a "set break point" command. The software break point would be set at a particular memory address location within the user program where the user wants to halt the user program when it is being executed.
After all the relevant registers and memory locations have been initialized (using the available monitor commands with the microprocessor running the monitor program), the user would enter a "monitor run command". This would cause the microprocessor to stop executing the monitor program and start executing the user program from the initialized user program counter. The microprocessor would continue to execute the user program until the software break point is reached. At this point, the microprocessor would stop executing the user program, save all its register values in a reserved area of memory, and start executing the monitor program again. The only method by which a user program may be halted and the monitor program be started is to set a break point in the user program.
To accomplish this, the monitor "set break point" command replaces an instruction in the user program with a trap instruction at the address of each desired software break point and temporarily stores the replaced user program instructions. The "monitor run" command then runs the user software until the first break point, i.e., the first trap instruction, is encountered. It "vectors" to a two word branch instruction that calls the monitor subroutine which handles software break points and replaces every trap instruction with the user instruction that earlier was replaced by the trap instruction. The monitor also automatically displays on the terminal screen the contents of all registers of the processor at the time that the program counter of the processor encountered the break point trap instruction.
Debugging a user program entails checking that the user program executes exactly the expected sequence of operations that the user program is designed to carry out. Ideally, all registers of the processor and any memory location that the user program affects would be checked for the expected values after every user program instruction the processor executes. In practice, because of the length of most programs, this is not practical and all the program variables are only checked at certain carefully chosen positions within the user program where break points are defined.
When a problem is encountered, it often is desirable to "home in" on the user instruction or instructions that are causing the problem. This can be done by repeatedly redefining the position of the software break points so that they move closer together in the user program. In this way, shorter and shorter steps are taken between each break point when the user program is run. In the limiting case, a set of break points would be defined consecutively in locations in the user program wherein it is suspected that erroneous user program code exists. The user program would be run until the first break point is encountered. The program variables would be examined. The user program then would be run from the first break point to the second; in effect, one more user instruction would be executed and the program variables again would be examined. This process would be repeated.
However, any monitor allows only a certain maximum number of break points to be set (typically four to ten), so if the user wishes to continue one step execution of the user program past the last break point in the user program, the break point would have to be redefined.
Most monitors that are executed in a system using a microprocessor whose instruction set includes a trap instruction have a "singe step command" which easily enables a user program to be executed one instruction at a time The sequence of events of a monitor single step command are as follows The monitor examines the op code in the memory whose address is given by the value of the user program counter. This is the op code that the user program will first execute if the monitor run command is executed. The monitor decodes the op code to determine the length of the whole instruction (for example, one word or two words) and then places a trace instruction in the next location just after it (after first saving the user instructions there). Thus, the monitor effectively sets a break point immediately after the next user instruction that is about to be executed. The monitor then executes a run command (as part of the single step command). The user program instruction is executed and the program counter is incremented to the address value of memory that contains the trap instruction. The trap instruction is executed, causing the user program to be halted and the monitor program to execute. The monitor program saves all the processor register values and replaces the trap instruction with the original saved user instruction. The user program counter now contains the address value of the next user program memory instruction, so the user may now again execute another single step command in order to advance forward again. This process simply uses one break point that is always carefully placed one instruction ahead in the user program.
Some user instructions require a slight modification to the above sequence of events when executing a monitor single step command. For example, consider the case when the user instruction about to be executed is a conditional branch instruction as shown by the memory diagram of FIG. 5. As the conditional branch 90 is executed, depending on the value of a flag that previously has been set, the user program either will branch to address 1005 or address 1006, as indicated by reference numerals 91 and 92, respectively. Hence, not only must a trap instruction be placed in location 1005 (after first saving the user instruction there), but another trap instruction also must be placed at address 1006, designated by reference numeral 92. Thus, a trap instruction always will be executed next, regardless which direction the branch instruction takes.
FIG. 5 also illustrates why typically only microprocessors containing a trap instruction as part of their instruction set are able to provide the single step monitor command. Consider a "call subroutine" instruction being used in place of the trap instruction. The call subroutine instruction is a two word instruction. So although a break point could be set at location 1005 of FIG. 5 by placing the call instruction op code at location 1005 and the argument of that op code at location 1006, the argument would be overwritten by the call instruction op code of the second break point being placed at 1006 with its argument at location 1007. Execution of the first call instruction op code at location 1005 then would cause an error in the monitor. This problem does not arise using the trap instruction to implement the single step monitor command, as the trap instruction is a single word instruction.
Many commonly used microprocessors include a number of trap instructions in their instruction sets, each of which "vectors" to a different predetermined location. Recently, however, high performance, high speed microprocessors having so-called "limited instruction sets" are being utilized for certain applications, such as high speed digital signal processors (DSP's). However, some such microprocessors contain no trap instructions, while others, such as the Texas Instruments TMS32020 include only one trap instruction in their instruction set. Although the single trap instruction could be used to write a software monitor for a TMS32020-based digital signal processing system, this would make that trap instruction unavailable for use in software to be executed by the system It would be very desirable to be able to provide an efficient software monitor for a TMS32020 based system, and yet make the entire limited instruction set thereof available to the system user.